package cn.eva.service.Impl;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationCredentialsNotFoundException;
import org.springframework.security.authentication.DisabledException;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import cn.eva.common.enums.CredentialType;
import cn.eva.common.enums.StudentStatus;
import cn.eva.common.enums.TeacherStatus;
import cn.eva.dao.EvaManagerMapper;
import cn.eva.dao.EvaStudentMapper;
import cn.eva.dao.EvaTeacherMapper;
import cn.eva.dao.SysMenuMapper;
import cn.eva.dao.SysRoleMenuMapper;
import cn.eva.dao.SysUserRoleMapper;
import cn.eva.dto.LoginUser;
import cn.eva.entity.EvaManager;
import cn.eva.entity.EvaStudent;
import cn.eva.entity.EvaTeacher;
import cn.eva.entity.SysMenu;
import cn.eva.entity.SysRole;
import cn.eva.entity.SysRoleMenuKey;
import cn.eva.example.EvaManagerExample;
import cn.eva.example.EvaStudentExample;
import cn.eva.example.EvaTeacherExample;
import cn.eva.example.SysMenuExample;
import cn.eva.example.SysRoleMenuExample;
import cn.eva.service.UserService;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private EvaTeacherMapper evaTeacherMapper;

    @Autowired
    private EvaStudentMapper evaStudentMapper;

    @Autowired
    private EvaManagerMapper evaManagerMapper;

    @Autowired
    private SysUserRoleMapper sysUserRoleMapper;

    @Autowired
    private SysRoleMenuMapper sysRoleMenuMapper;

    @Autowired
    private SysMenuMapper sysMenuMapper;

    @Override
    public LoginUser getUserInfoByAccount(String username) {
        LoginUser loginUser = new LoginUser();
        String[] params = username.split("\\|");
        // 真正的用户名
        username = params[0];
        if (params.length > 1) {
            //登录类型
            CredentialType credentialType = CredentialType.valueOf(params[1]);
            if (CredentialType.TEACHER == credentialType) {
                //教师
                loginUser = handlerTeacherLogin(username);
            } else if (CredentialType.STUDENT == credentialType) {
                //学生
                loginUser = handlerStudentLogin(username);
            } else if (CredentialType.ADMIN == credentialType) {
                //管理员
                loginUser = handlerAdminSmsLogin(username);
            }
        }
        if (StringUtils.isNotBlank(loginUser.getUuid())) {
            this.setRoleAndMenu(loginUser.getUuid(), loginUser);
        }
        if (StringUtils.isBlank(loginUser.getUuid())) {
            throw new AuthenticationCredentialsNotFoundException("用户名或密码错误");
        }
        return loginUser;
    }

    private LoginUser handlerAdminSmsLogin(String username) {
        LoginUser loginUser = new LoginUser();
        EvaManagerExample example = new EvaManagerExample();
        example.createCriteria().andMAccountEqualTo(username);
        List<EvaManager> list = evaManagerMapper.selectByExample(example);
        if (!CollectionUtils.isEmpty(list)) {
            EvaManager manager = list.get(0);
            loginUser.setUuid(manager.getmId());
            loginUser.setUser(manager);
            loginUser.setUsername(manager.getmAccount());
            loginUser.setPassword(manager.getmPass());
            loginUser.setType(CredentialType.ADMIN.toString());
            loginUser.setEnabled(true);
        }
        return loginUser;
    }

    private LoginUser handlerStudentLogin(String username) {
        LoginUser loginUser = new LoginUser();
        EvaStudentExample example = new EvaStudentExample();
        example.createCriteria().andSNoEqualTo(username);
        List<EvaStudent> list = evaStudentMapper.selectByExample(example);
        if (!CollectionUtils.isEmpty(list)) {
            EvaStudent student = list.get(0);
            loginUser.setUuid(student.getsId());
            loginUser.setUser(student);
            loginUser.setUsername(student.getsNo());
            loginUser.setPassword(student.getsPass());
            loginUser.setType(CredentialType.STUDENT.toString());
            //学生类型（1在校2退学3休学）
            loginUser.setEnabled(StudentStatus.IN.getCode().equals(student.getsType()));
        }
        return loginUser;
    }

    private LoginUser handlerTeacherLogin(String username) {
        LoginUser loginUser = new LoginUser();
        EvaTeacherExample example = new EvaTeacherExample();
        example.createCriteria().andTNoEqualTo(username);
        List<EvaTeacher> list = evaTeacherMapper.selectByExample(example);
        //教师状态（1在职0离职）
        if (!CollectionUtils.isEmpty(list)) {
            EvaTeacher teacher = list.get(0);
            loginUser.setUuid(teacher.gettId());
            loginUser.setUser(teacher);
            loginUser.setUsername(teacher.gettNo());
            loginUser.setPassword(teacher.gettPass());
            loginUser.setType(CredentialType.TEACHER.toString());
            if (TeacherStatus.Resignation.getCode().equals(teacher.gettStatus())) {
                throw new DisabledException("您已离职，登录失败");
            }
            loginUser.setEnabled(TeacherStatus.Incumbent.getCode().equals(teacher.gettStatus()));
        }
        return loginUser;
    }

    /**
     * 设置角色和权限
     * @Title: selectRoleByUid
     * @param @return
     * @return Object
     * @throws
     */
    private void setRoleAndMenu(String uid, LoginUser loginUser) {
        List<SysRole> roles = sysUserRoleMapper.selectRoleByUid(uid);
        loginUser.setRoles(roles);
        loginUser.setMenus(new ArrayList<SysMenu>());
        if (!CollectionUtils.isEmpty(roles)) {
            //查menu（菜单）
            List<Long> rLongs = roles.parallelStream().map(SysRole::getrId).collect(Collectors.toList());
            SysRoleMenuExample example = new SysRoleMenuExample();
            example.createCriteria().andRoleIdIn(rLongs);
            List<SysRoleMenuKey> roleMenuKeys = sysRoleMenuMapper.selectByExample(example);
            if (!CollectionUtils.isEmpty(roleMenuKeys)) {
                List<Long> mids = roleMenuKeys.parallelStream().map(SysRoleMenuKey::getMenuId)
                        .collect(Collectors.toList());
                SysMenuExample example1 = new SysMenuExample();
                example1.createCriteria().andIdIn(mids);
                List<SysMenu> menus = sysMenuMapper.selectByExample(example1);
                loginUser.setMenus(menus);
            }
        }
    }

}
